<?php
/**
 * static class: Blib_Utility_Xml
 *
 * @author bbqq <toughgamer@gmail.com>
 * @package com.blib.utility
 * @copyright bbqq qstufie.com
 */
class Blib_Utility_Xml
{
	/**
	 * validate xml
	 *
	 * @param str $xml the xml data
	 *
	 * @return bool
	 */
	public static function validate($xml)
	{
		libxml_use_internal_errors(true);

		// test via load
		if (!simplexml_load_string($xml)) {
			libxml_clear_errors();
			return false;
		}

		// otherwise it's all good
		return true;

	}// end validate


	/**
	 * read xml from file
	 *
	 * @param str $filename the filename
	 *
	 * @return SimpleXMLElement
	 */
	public static function readFile($filename)
	{
		if (!file_exists($filename)) {
			return false;
		}

		$src = file_get_contents($filename);
		return self::readString($src);

	}// end readFile


	/**
	 * read data into xml object
	 *
	 * @param str $xml the xml
	 *
	 * @return SimpleXMLElement
	 */
	public static function readString($xml)
	{
		libxml_use_internal_errors(true);
		$xml = simplexml_load_string($xml);
		if (!$xml) {
			self::_xmlException('XML Structure Not Valid');
		} else {
			return $xml;
		}

	}// end readString


	/**
	 * read from remote url
	 *
	 * @param str $url the url
	 *
	 * @return SimpleXMLElement
	 */
	public static function readUrl($url)
	{
		// use http request...
        $src = @file_get_contents($url);
		return self::readString($src);

	}// end readUrl


	/**
	 * convert xml into array
	 *
	 * @param SimpleXMLElement $xml the input
	 *
	 * @return array
	 */
	public static function xmlToArray(SimpleXMLElement $xml)
	{
		$array = array();
		$xml   = (array) $xml;

		foreach ($xml as $key => $child) {
			if ($child instanceof SimpleXMLElement) {
				$child = self::xmlToArray($child);
			}

			$array[$key] = $child;
		}

		// kill the null value
		if (empty($array)) {
			return null;
		}

		return $array;

	}// end xmlToArray

	/*--------------------------------[private functions]--------------------------------*/

	/**
	 * throw some proper exception
	 *
	 * @param str   $message the message
	 *
	 * @return void
	 */
	private static function _xmlException($message)
	{
		// presumably the error is there...
		$errors = libxml_get_errors();
		defined('BR') or define('BR', "\n");
		if (is_array($errors)) {
			$message .= BR . 'Errors:';
			foreach ($errors as $error) {
				if ($error instanceof libXMLError) {
					$message .= BR . 'CODE:   ' . $error->code .
					BR . 'Message:' . $error->message .
					BR . 'Column: ' . $error->column .
					BR . 'line:   ' . $error->line;
				}
			}
		}

		// clean it
		libxml_clear_errors();
		throw new Exception($message);

	}// end _xmlException

}// end Blib_Utility_Xml
?>